﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;

namespace Base.Contracts
{
	public static class ExpressionExtension
	{

		/// <summary>
		/// This method extracts the name of a property out of a <c>UnaryExpression</c> or a <c>MemberExpression</c>. 
		/// </summary>
		/// <param name="expression">The <c>Expression</c> to extract the name of the property from</param>
		/// <returns>
		/// The string that contains just the "encoded" property name.
		/// </returns>
		[System.Diagnostics.DebuggerStepThrough()]
		public static string ToMagicString<T>(this Expression<Func<T>> expression)
		{
			if (expression == null)
			{
				return string.Empty;
			}
			//For basic data types (int, string, ...)
			if (expression.Body is UnaryExpression)
			{
				UnaryExpression unaryExpression = (UnaryExpression)expression.Body;
				return ToMagicString((MemberExpression)unaryExpression.Operand);
			}

			//For complex dataType
			if (expression.Body is MemberExpression)
			{
				return ToMagicString((MemberExpression)expression.Body);
			}

			throw new NotImplementedException();
		}

		/// <summary>
		/// This method extracts the name of a property out of a <c>MemberExpression</c>. 
		/// </summary>
		/// <param name="expression">The <c>MemberExpression</c> to extract the name of the property from</param>
		/// <returns>
		/// The string that contains just the "encoded" property name.
		/// </returns>
		[System.Diagnostics.DebuggerStepThrough()]
		public static string ToMagicString(MemberExpression expression)
		{
			return expression.Member.Name;
		}

		/// <summary>
		/// This method compare two instances of <c>UnaryExpression</c> or a <c>MemberExpression</c>. 
		/// </summary>
		/// <param name="expression1">The first <c>Expression</c> to compare with</param>
		/// <param name="expression">The second <c>Expression</c> to compare with</param>
		/// <returns>
		/// The boolean if the two expressions target the same property.
		/// </returns>
		public static bool IsEqualTo<T>(this Expression<Func<T>> expression1, Expression<Func<T>> expression)
		{
			return (expression1.ToMagicString() == expression.ToMagicString());
		}
	}
}
